﻿namespace StockSharp.Algo.Indicators.Misc
{
	using System;
	using System.Linq;

	using StockSharp.Algo.Indicators.Trend;

	/// <summary>
	/// Среднее отклонение.
	/// </summary>
	public class MeanDeviation : LengthIndicator<decimal>
	{
		/// <summary>
		/// Создать <see cref="MeanDeviation"/>.
		/// </summary>
		public MeanDeviation()
			: base(typeof(decimal))
		{
			Sma = new SimpleMovingAverage {Length = 5};
		}

		/// <summary>
		/// Длина периода.
		/// </summary>
		public override int Length
		{
			get
			{
				return Sma.Length;
			}
			set
			{
				Sma.Length = value;
				Reset();
			}
		}

		/// <summary>
		/// Скользящая средняя.
		/// </summary>
		public SimpleMovingAverage Sma { get; private set; }

		/// <summary>
		/// Сформирован ли индикатор.
		/// </summary>
		public override bool IsFormed { get { return Sma.IsFormed; } }

		/// <summary>
		/// Обработать входное значение.
		/// </summary>
		/// <param name="input">Входное значение.</param>
		/// <returns>Результирующее значение.</returns>
		protected override decimal OnProcess(IIndicatorValue input)
		{
            var val = input.GetValue<decimal>();

            if(input.IsFinal)
			    Buffer.Add(val);

			var smaValue = Sma.Process(input).GetValue<decimal>();

			if (Buffer.Count > Length)
				Buffer.RemoveAt(0);

			// считаем значение отклонения
			var md = input.IsFinal ?
                Buffer.Sum(t => Math.Abs(t - smaValue)) :
                Buffer.Skip(IsFormed ? 1 : 0).Sum(t => Math.Abs(t - smaValue)) + Math.Abs(val - smaValue);

			return md / Length;
		}
	}
}
